package com.baofu.paycore.service;

import com.baofu.paycore.biz.model.BackPayBO;
import com.baofu.paycore.biz.paycore.handler.impl.PreAuthCancelHandler;
import com.baofu.paycore.biz.paycore.handler.impl.PreAuthHandler;
import com.baofu.paycore.common.utils.ExceptionUtil;
import com.baofu.paycore.manager.model.preAuth.PreAuthBO;
import com.baofu.paycore.manager.storer.PreAuthRepository;
import com.baofu.paycore.service.converter.BO2DTOConverter;
import com.baofu.paycore.service.facade.AuthorizeServiceFacade;
import com.baofu.paycore.service.facade.model.CancelPayDTO;
import com.baofu.paycore.service.facade.model.CancelResDTO;
import com.baofu.paycore.service.facade.model.ReverseResDTO;
import com.baofu.paycore.service.facade.model.authorize.AuthorizeCancelDTO;
import com.baofu.paycore.service.facade.model.authorize.AuthorizeDTO;
import com.baofu.paycore.service.facade.model.authorize.AuthorizeResDTO;
import com.baofu.paycore.service.facade.model.authorize.AuthorizeReverseDTO;
import com.baofu.paycore.service.factory.impl.PreAuthCancelFactoryImpl;
import com.baofu.paycore.service.factory.impl.PreAuthFactoryImpl;
import com.baofu.paycore.service.validate.impl.preAuth.PreAuthCancelValidate;
import com.baofu.paycore.service.validate.impl.preAuth.PreAuthValidate;
import com.system.commons.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.slf4j.helpers.SystemMarker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 预授权服务
 *
 * <p>
 *  1.预授权接口
 *  2.预授权撤销接口
 *  3.预授权冲正接口
 *  4.预授权撤销冲正接口
 * </p>
 * User: xin deng  Date: 16/8/30 ProjectName: paycore Version: 1.0
 */
@Slf4j
@Service
public class AuthorizeService implements AuthorizeServiceFacade {

    /**
     * 预授权校验
     */
    @Autowired
    private PreAuthValidate preAuthValidate;

    /**
     * 预授权撤销单校验
     */
    @Autowired
    private PreAuthCancelValidate preAuthCancelValidate;

    /**
     * 预授权工厂服务
     */
    @Autowired
    private PreAuthFactoryImpl payBaseFactory;

    /**
     * 预授权撤销工厂服务
     */
    @Autowired
    private PreAuthCancelFactoryImpl preAuthCancelFactory;

    /**
     * 预授权服务
     */
    @Autowired
    private PreAuthRepository preAuthRepository;

    /**
     * 预授权处理服务
     */
    @Autowired
    private PreAuthHandler preAuthHandler;

    /**
     * 预授权撤销处理服务
     */
    @Autowired
    private PreAuthCancelHandler preAuthCancelHandler;

    /**
     * 预授权接口
     *
     * @param authorizeDTO 预授权请求参数
     * @return 预授权响应
     * response.isSuccess()标示方法的远程调用状态，方法实际执行结果从result 取值
     */
    @Override
    public Result<AuthorizeResDTO> authorize(AuthorizeDTO authorizeDTO, String transLogId) {
        Result<AuthorizeResDTO> result = null;
        boolean flag = false;

        try {
            MDC.put(SystemMarker.TRACE_LOG_ID, transLogId);

            log.info("预授权接口请求信息：请求参数：{}", authorizeDTO);

            flag = preAuthValidate.lock(authorizeDTO);

            //1、请求对象参数校验
            preAuthValidate.paramsValidate(authorizeDTO);

            //2、请求对象转换
            PreAuthBO preAuthBO = payBaseFactory.build(authorizeDTO);
            preAuthBO.setTradeLogId(transLogId);

            //3、消费相关信息落地
            preAuthRepository.addOrder(preAuthBO);

            //4、业务流程处理
            BackPayBO backPayBO = preAuthHandler.process(preAuthBO);

            //5、接口返回对象生成
            AuthorizeResDTO authorizeResDTO = BO2DTOConverter.getAuthorizeResDTO(backPayBO);
            result = new Result<>(authorizeResDTO);

        } catch (Exception e) {

            log.error("预授权 异常 EXCEPTION:{}", e);
            result = ExceptionUtil.doExceptionService(e, AuthorizeResDTO.class);
        } finally {

            log.info("预授权 响应:{}",result);
            preAuthValidate.release(authorizeDTO,flag);
            MDC.clear();
        }
        return result;
    }

    /**
     * 预授权撤销接口
     *
     * @param cancelPayDTO 预授权撤销请求参数
     * @return 预授权撤销响应
     * response.isSuccess()标示方法的远程调用状态，方法实际执行结果从result 取值
     */
    @Override
    public Result<CancelResDTO> authorizeCancel(CancelPayDTO cancelPayDTO, String transLogId) {
        Result<CancelResDTO> result = null;
        boolean flag = false;
        try {
            MDC.put(SystemMarker.TRACE_LOG_ID, transLogId);

            log.info("预授权撤销接口请求信息：请求参数：{}", cancelPayDTO);

            flag = preAuthCancelValidate.lock(cancelPayDTO);

            //1、请求对象参数校验
            preAuthCancelValidate.paramsValidate(cancelPayDTO);

            PreAuthBO origPreAuth = preAuthCancelValidate.validateUniqueOrder(cancelPayDTO, preAuthRepository);

            //2、请求对象转换
            PreAuthBO preAuthBO = preAuthCancelFactory.build(cancelPayDTO, origPreAuth);

            //3、消费相关信息落地
            preAuthRepository.addOrder(preAuthBO);

            //4、业务流程处理
            BackPayBO backPayBO = preAuthCancelHandler.process(preAuthBO);

            //5、接口返回对象生成
            CancelResDTO cancelResDTO = BO2DTOConverter.getAuthorizeCancelResDTO(backPayBO);
            result = new Result<>(cancelResDTO);

        } catch (Exception e) {

            log.error("预授权撤销 异常 EXCEPTION:{}", e);
            result = ExceptionUtil.doExceptionService(e,CancelResDTO.class);
        } finally {

            log.info("预授权撤销 响应:{}", result);
            preAuthCancelValidate.release(cancelPayDTO,flag);
            MDC.clear();
        }
        return result;
    }

    /**
     * 预授权冲正接口
     *
     * @param reverseDTO 预授权冲正请求参数
     * @return 预授权冲正响应
     * response.isSuccess()标示方法的远程调用状态，方法实际执行结果从result 取值
     */
    @Override
    public Result<ReverseResDTO> authorizeReverse(AuthorizeReverseDTO reverseDTO, String transLogId) {
        return null;
    }

    /**
     * 预授权撤销冲正接口
     *
     * @param cancelAuthorizeDTO 预授权撤销冲正请求参数
     * @return 预授权撤销冲正响应
     * response.isSuccess()标示方法的远程调用状态，方法实际执行结果从result 取值
     */
    @Override
    public Result<CancelResDTO> cancelAuthorizeReverse(AuthorizeCancelDTO cancelAuthorizeDTO, String transLogId) {
        return null;
    }
}
